<?php

namespace app\sys\job;

use think\queue\Job;
use think\Db;

// 发送模板消息的mq消费者
class postQueue
{
    public function fire(Job $job, $payload)
    {
        echo 'start'.PHP_EOL;
        $t1 = microtime(true);
        $done = $this->consume($payload);
        if ($done) {
            $job->delete();
        } else {
            if ($job->attempts() > 2) {
                Db::name('job_fail')->insert(['ct' => time(), 'type' => '失败3次', 'para' => $payload]);
                $job->delete();
            } else {
                $job->release(3);
            }
        }
        $t2 = microtime(true);
        echo '耗时'.round($t2 - $t1, 4).'秒'.PHP_EOL;
    }

    private function consume($payload)
    {
        try {
            if ($payload['service_url']) {
                $service_url = '';
                if ('发送小程序模板消息' == $payload['type'] || '发送客服消息' == $payload['type']) {
                    $access_token = cache('wx_access_token');
                    if (!$access_token) {
                        cache('wx_access_token', null);
                        $wx_service = new \wx\WeixinService();
                        return false;
                    }
                } elseif ('发送公众号模板消息' == $payload['type']) {
                    $access_token = cache('wxgzh_access_token');
                    if (!$access_token) {
                        cache('wxgzh_access_token', null);
                        $wxgzh_service = new \wx\WxgzhService();
                        return false;
                    }
                }

                $service_url = sprintf($payload['service_url'], $access_token);

                if (!$service_url) {
                    return false;
                }
                $result = post($service_url, $payload['para']);
                if (false === $result) {
                    // Db::name('job_fail')->insert(['ct' => time(), 'type' => '发送失败', 'para' => $payload]);

                    return false;
                } else {
                    $result = json_decode($result, true);
                    if (0 == $result['errcode']) {
                        // Db::name('job_fail')->insert(['ct' => time(), 'type' => '收到正常结果', 'para' => $payload, 'result' => $result]);

                        return true;
                    } else {
                        if (45047 == $result['errcode']) {
                            // 客服消息发送失败不记录（45047 out of response count limit hint）
                            return true;
                        }
                        
                        if (40001 == $result['errcode']) {
                            // 重新获取token
                            cache('wx_access_token', null);
                            cache('wxgzh_access_token', null);
                            $wx_service = new \wx\WeixinService();
                            $wxgzh_service = new \wx\WxgzhService();
                        }
                        
                        Db::name('job_fail')->insert(['ct' => time(),'service_url'=>$service_url,'type'=>$payload['type'], 'para' => $payload['para'], 'result' => $result['errcode'].$result['errmsg']]);

                        return false;
                    }
                }
            } else {
                return false;
            }
        } catch (\Exception $e) {
            echo 'Job Process Failed!';
            Db::name('job_fail')->insert(['ct' => time(), 'type' => '异常', 'para' => $payload, 'exception' => $e]);

            return false;
        }
    }

    public function failed($data)
    {
        // ...任务达到最大重试次数后，失败了
        echo ' Job failed!'.PHP_EOL;
    }
}
